/*
 * Copyright 2024 The CHANGLEI Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import 'dart:io';

import 'package:code_builder/code_builder.dart' as code;
import 'package:fibber/src/logger.dart';
import 'package:fibber/src/name.dart';
import 'package:fibber/src/spec.dart';
import 'package:path/path.dart' as path;

extension NamedFileSystemEntity on FileSystemEntity {
  String get canonicalized => path.canonicalize(this.path);

  String get name => path.basename(canonicalized);

  String get nameWithoutExtension => path.basenameWithoutExtension(canonicalized);
}

void writeSpecsFile(
  String output,
  String name,
  List<Spec> specs, {
  List<Import> imports = const [],
  List<String> ignores = const [],
}) {
  final library = code.Library((builder) {
    builder
      ..name = name.snakeCased
      ..comments.addAll([
        r'GENERATED CODE - DO NOT MODIFY BY HAND',
        r'',
        r'**************************************************************************',
        r'Generator: Flutter fibber IDE plugin',
        r'Made by Changlei',
        r'**************************************************************************',
      ])
      ..ignoreForFile.addAll([
        r'type=lint',
        ...ignores,
      ])
      ..docs.add('/// Library: ${name.titleCased}')
      ..body.addAll(imports.map((e) => e.spec))
      ..body.addAll(specs.map((e) => e.spec));
  });
  final codeText = dartfmt.format('${library.accept(emitter)}');

  final generatedFile = File(path.join(output, '${name.snakeCased}.dart'));
  if (generatedFile.existsSync()) {
    generatedFile.deleteSync(recursive: true);
  }
  generatedFile.createSync(recursive: true);
  final writer = generatedFile.openWrite();
  writer.flush();
  writer.write(codeText);
  writer.close();
  Level.info.writeln('生成文件 -> ${generatedFile.path}');
}
